package com.accenture.fd.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.accenture.fd.dao.DtoSourceDao;
import com.accenture.fd.entity.DtoToSource;
import com.accenture.fd.service.CreateSourceService;
import com.accenture.fd.utils.generator.model.DtoModel;
import com.accenture.fd.utils.generator.model.EventModel;

@Service
public class CreateSourceServiceImpl implements CreateSourceService {

	@Autowired
	private DtoSourceDao dtoSourceDao;

	@Override
	public Map<String, Object> createSource(String classId, String classPakage, String classType) {

		List<DtoToSource> modelList = this.dtoSourceDao.findById(classPakage + "." + classId);

		Map<String, Object> tempData = new HashMap<>();
		tempData.put("packageName", classPakage + "." + classId);
		tempData.put("classNameEk", classId);
		tempData.put("classNameKz", modelList.get(0).getClassComment());

		String tempName = "";
		if ("Bean".equals(classType)) {
			tempName = "Bean";
			this.setBeanMap(classId, modelList, tempData);
		} else if ("DTO".equals(classType)) {
			tempName = "Dto";
			this.setDtoMap(modelList, tempData);
		} else if ("Facade".equals(classType)) {
			tempName = "Facade";
			this.setFacadeMap(classId, modelList, tempData);
		} else if ("FacadeImpl".equals(classType)) {
			tempName = "FacadeImpl";
			this.setFacadeImplMap(classId, modelList, tempData);
		}
		tempData.put("tempName", tempName);
		return tempData;
	}

	@Override
	public Map<String, Object> createJunit(Map<String, Object> map) {

		if (map.containsKey("packageName")) {
			String value = map.get("packageName").toString();
            map.put("packageName", value);
        }
		if (map.containsKey("dtoList")) {
			this.addValue(map);
        }
		return map;

	}

	private void addValue(Map<String,Object> map) {

		List<DtoModel> dtoModelList = (List<DtoModel>)map.get("dtoList");

		for(int i = 0 ; i < dtoModelList.size();i++) {

			DtoModel model = dtoModelList.get(i);
			//boolean、byte、char、short、int、float、double、long
			//Boolean、Byte、Character、Short、Integer、Float、Double、Long
			//String
			//List、Map
			if("String".equals(model.getFieldType())){
				model.setMockValue("\""+i+"\"");
			}else if("int".equals(model.getFieldType())){
				model.setMockValue(i);
			}else {
				model.setMockValue(null);
			}
		}

	}

	private void setBeanMap(String classId, List<DtoToSource> modelList, Map<String, Object> tempData) {

		tempData.put("menuId", modelList.get(0).getScreenId());
		tempData.put("classContent", modelList.get(0).getClassComment());
		tempData.put("classNameEkScreen", classId.replace("Bean", ""));

		List<EventModel> eventModelList = modelList.stream().map(model -> {
			EventModel eventModel = new EventModel();
			eventModel.setEventNameKz(model.getNameKanji());
			eventModel.setEventContent(model.getNameKanji());
			eventModel.setEventId(model.getFieldType());
			eventModel.setEventNameEk(model.getNamePhysics());
			return eventModel;
		}).collect(Collectors.toList());
		tempData.put("eventList", eventModelList);
	}

	private void setDtoMap(List<DtoToSource> modelList, Map<String, Object> tempData) {

		List<DtoModel> dtoModelList = modelList.stream().map(model -> {
			DtoModel dtoModel = new DtoModel();
			dtoModel.setFieldNameEk(model.getNamePhysics());
			dtoModel.setFieldNameEkUpper(this.stringToUpperCase(model.getNamePhysics()));
			dtoModel.setFieldNameKz(model.getNameKanji());
			dtoModel.setFieldType(model.getFieldType());
			return dtoModel;
		}).collect(Collectors.toList());
		tempData.put("dtoList", dtoModelList);
	}

	private void setFacadeMap(String classId, List<DtoToSource> modelList, Map<String, Object> tempData) {

		tempData.put("classContent", modelList.get(0).getClassComment());
		tempData.put("classNameEkEvent", classId.replace("Facade", ""));

		List<EventModel> eventModelList = modelList.stream().map(model -> {
			EventModel eventModel = new EventModel();
			eventModel.setEventNameKz(model.getNameKanji());
			eventModel.setEventContent(model.getNameKanji());
			eventModel.setEventId(model.getFieldType());
			eventModel.setEventNameEk(this.stringToUpperCase(model.getNamePhysics()));
			return eventModel;
		}).collect(Collectors.toList());
		tempData.put("eventList", eventModelList);
	}

	private void setFacadeImplMap(String classId, List<DtoToSource> modelList, Map<String, Object> tempData) {

		tempData.put("classContent", modelList.get(0).getClassComment());
		tempData.put("classNameEkEvent", classId.replace("Facade", ""));

		List<EventModel> eventModelList = modelList.stream().map(model -> {
			EventModel eventModel = new EventModel();
			eventModel.setEventNameKz(model.getNameKanji());
			eventModel.setEventContent(model.getNameKanji());
			eventModel.setEventId(model.getFieldType());
			eventModel.setEventNameEk(this.stringToUpperCase(model.getNamePhysics()));
			return eventModel;
		}).collect(Collectors.toList());
		tempData.put("eventList", eventModelList);
	}

	// 1桁目を大文字に変換する
	private String stringToUpperCase(String changeStr) {
		String part1 = changeStr.substring(0, 1).toUpperCase();
		String part2 = changeStr.substring(1);
		return part1 + part2;
	}

}
